//
//  QRCodeViewController.swift
//  DSWeiBo
//
//  Created by H on 16/5/19.
//  Copyright © 2016年 Mr.Lin. All rights reserved.
//

import UIKit
import AVFoundation

class QRCodeViewController: UIViewController,UITabBarDelegate {
        /// 冲击波
    @IBOutlet weak var scanLineView: UIImageView!
        /// 扫描容器高度约束
    @IBOutlet weak var containerHeightCons: NSLayoutConstraint!
        /// 冲击波视图顶部约束
    @IBOutlet weak var scanLineCons: NSLayoutConstraint!

    @IBAction func closeBtnClick(sender: UIBarButtonItem) {
        dismissViewControllerAnimated(true , completion: nil)
    }
        /// 保存扫描到的结果
    @IBOutlet weak var resultlabel: UILabel!
    
    /**
     监听名片点击
     */
    @IBAction func myCardClick(sender: AnyObject) {
        
        navigationController?.pushViewController(QRMyCodeViewController(), animated: true)
    }
    //底部自定义tabbar
    @IBOutlet weak var customTabBar: UITabBar!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //设置底部默认选中第0个
        customTabBar.selectedItem = customTabBar.items![0]
        customTabBar.delegate = self
    }
    
    override func viewWillAppear(animated: Bool) {
        super.viewDidAppear(true)
        //开启冲击波动画
            startAnimator()
        //开始扫描
        startScan()
    }
    
    func startScan(){
        //1 判断是否能够将输入添加到会话中
        if !session.canAddInput(deviceInput) {
            return
        }
        //2. 判断是否能够将输出添加到会话中
        if !session.canAddOutput(output) {
            return
        }
        //3. 将输入和输出都添加到会话总
        session.addInput(deviceInput)
        print(output.metadataObjectTypes)
        session.addOutput(output)
        print(output.metadataObjectTypes)
        //4. 设置输出能够解析的数据类型
        //注意 设置能够解析的数据类型 一定要在输出对象添加到会话之后设置 否则会报错
        output.metadataObjectTypes = output.availableMetadataObjectTypes
        //5. 设置输出对象的代理  主要解析成功就会通知代理
        output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        //添加预览图谶
        view.layer.insertSublayer(previewLayer,atIndex: 0)
        
        //添加绘制图层到预览图层上
        previewLayer.addSublayer(drawLayer)
        //6. 告诉session开始扫描
        session.startRunning()
    }
    
  //MARK: - UITabBarDelegate
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
        //1.修改容器的高度
        if item.tag == 1 {
            self.containerHeightCons.constant = 300
            print("二维码")
        }else{
            self.containerHeightCons.constant = 150
            print("条形码")
        }
        
        //2.停止动画
        self.scanLineView.layer.removeAllAnimations()
        
        //3.重新开始动画
        startAnimator()

    }
    /**
     执行动画
     */
    private func startAnimator(){
        //让约束从顶部开始
        scanLineCons.constant = -containerHeightCons.constant
        view.layoutIfNeeded()
        //冲击波动画
        UIView.animateWithDuration(2.0, animations: {
            //修改约束
            self.scanLineCons.constant = self.containerHeightCons.constant
            //设置动画指定的次数
            UIView.setAnimationRepeatCount(MAXFLOAT)
            //强制更行界面
            self.view.layoutIfNeeded()
        })
    }
    
    
    //MARK: 懒加载
    //会话
    private lazy var session : AVCaptureSession = AVCaptureSession()
    //拿到输入设备
    private lazy var deviceInput:AVCaptureDeviceInput? = {
       let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        do{
            //创建输入设备
            let input = try AVCaptureDeviceInput(device:device)
            return input
        }catch{
                print(error)
                return nil
        }
    }()
    //拿到输出设备
    private lazy var output:AVCaptureMetadataOutput = AVCaptureMetadataOutput()
    
    //创建预览图
    private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let layer = AVCaptureVideoPreviewLayer(session:self.session)
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()
    
    //创建用于绘制边线的图层
    private lazy var drawLayer:CALayer = {
       let layer = CALayer()
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()
}

extension QRCodeViewController:AVCaptureMetadataOutputObjectsDelegate {
    //只要解析到数据 就会调用
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!){
//        print(metadataObjects)
        //使用stringValue
        resultlabel.text = metadataObjects.last?.stringValue
        
        //2。 获取扫描到的二维码位置
        print(metadataObjects.last)
        //2.1 转换坐标
        for obj in metadataObjects{
            //2.1.1 判断当前获取到的数据 是否是几期可识别的类型
            if obj is AVMetadataMachineReadableCodeObject {
                let codeObj = previewLayer.transformedMetadataObjectForMetadataObject(obj as! AVMetadataObject) as! AVMetadataMachineReadableCodeObject
                print(codeObj)
                //2.1.3绘制图形
                drawCorners(codeObj)
            }
        
        }
    }
    /**
     绘制图形
     
     - parameter codeObj: 保存了坐标的对象
     */
    private func drawCorners(codeObj:AVMetadataMachineReadableCodeObject){
        
        if codeObj.corners.isEmpty {
            return
        }
        
        clearDrawLayer()
        
        //1.创建图层
        let layer = CAShapeLayer()
        layer.lineWidth = 4
        layer.strokeColor = UIColor.redColor().CGColor
        layer.fillColor = UIColor.clearColor().CGColor
        //2.创建路径
//        layer.path = UIBezierPath(rect:CGRect(x: 100,y: 300,width: 200,height: 200)).CGPath
        let path = UIBezierPath()
        var point = CGPointZero
        var index: Int = 0
        //2.1移动到第一个点
        CGPointMakeWithDictionaryRepresentation((codeObj.corners[index++] as! CFDictionaryRef), &point)
        path.moveToPoint(point)
        //2.2移动到其他的点
        while index < codeObj.corners.count {
            CGPointMakeWithDictionaryRepresentation((codeObj.corners[index++] as! CFDictionaryRef), &point)
            path.addLineToPoint(point)
        }
        //2.3关闭路径
        path.closePath()
        //2.4绘制路劲
        layer.path = path.CGPath
        
        //3.将绘制好的图层添加到drawLayer上
        drawLayer.addSublayer(layer)
    }
    //清空边线
    private func clearDrawLayer(){
        if drawLayer.sublayers == nil {
            return
        }
        for layer in drawLayer.sublayers!{
            layer.removeFromSuperlayer()
        }
    }
}
